package com.thinkverse.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.thinkverse.user.dto.*;
import com.thinkverse.user.entity.User;
import com.thinkverse.user.entity.VerificationCode;
import com.thinkverse.user.enums.ClaimStatusEnum;
import com.thinkverse.user.enums.RoleEnum;
import com.thinkverse.user.mapper.UserMapper;
import com.thinkverse.user.mapper.VerificationCodeMapper;
import com.thinkverse.user.service.AuthService;
import com.thinkverse.user.util.EmailService;
import com.thinkverse.user.util.RandomCodeUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

/**
 * AuthServiceImpl
 * - 注意：JWT 签发由网关或单独 auth 服务完成。如果需要在此生成 JWT，请接入 common.JwtUtil。
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AuthServiceImpl implements AuthService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private VerificationCodeMapper codeMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private EmailService emailService;

    @Override
    @Transactional
    public void sendRegisterCode(VerifyCodeRequestDTO request) {
        String email = request.getEmail();
        // 生成 6 位验证码
        String code = RandomCodeUtil.generateNumericCode(6);
        LocalDateTime now = LocalDateTime.now();
        VerificationCode vc = new VerificationCode();
        vc.setEmail(email);
        vc.setCode(code);
        vc.setType("REGISTER");
        vc.setCreatedAt(now);
        vc.setExpireTime(now.plusMinutes(15));
        codeMapper.insert(vc);

        // 发送验证码邮件
        String subject = "【注册验证码】";
        // 邮件内容（HTML格式，更美观）
        String content = String.format("""
                <div style="font-family: 'Microsoft YaHei', sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">
                    <h2 style="color: #333;">注册验证码</h2>
                    <p>您好！您正在注册账号，您的验证码是：</p>
                    <div style="font-size: 24px; font-weight: bold; color: #2c3e50; margin: 20px 0;">%s</div>
                    <p>验证码有效期为15分钟，请尽快完成注册。</p>
                    <p style="color: #999; font-size: 12px;">如果不是您本人操作，请忽略此邮件。</p>
                </div>
                """, code);

        // 调用邮件服务发送
        emailService.sendHtmlEmail(email, subject, content);
        log.info("注册验证码 {} 已发送至邮箱 {}", code, email);
    }

    @Override
    @Transactional
    public Long register(RegisterRequestDTO request) {
        // 验证验证码
        QueryWrapper<VerificationCode> qw = new QueryWrapper<>();
        qw.eq("email", request.getEmail())
                .eq("type", "REGISTER")
                .orderByDesc("created_at")
                .last("LIMIT 1");
        VerificationCode vc = codeMapper.selectOne(qw);
        if (vc == null || vc.getExpireTime() == null || vc.getExpireTime().isBefore(LocalDateTime.now())
                || !vc.getCode().equals(request.getVerifyCode())) {
            throw new RuntimeException("验证码无效或已过期");
        }

        // 检查邮箱是否已注册
        QueryWrapper<User> q2 = new QueryWrapper<>();
        q2.eq("email", request.getEmail());
        User exist = userMapper.selectOne(q2);
        if (exist != null) {
            throw new RuntimeException("该邮箱已注册");
        }

        // 创建用户
        User user = new User();
        user.setUsername(request.getUsername());
        user.setEmail(request.getEmail());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setAvatar("/images/default.png");
        user.setRole(RoleEnum.USER);
        user.setClaimStatus(ClaimStatusEnum.UNCLAIMED);
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());

        userMapper.insert(user);
        return user.getId();
    }

    @Override
    public LoginResponse login(LoginRequestDTO request) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("email", request.getEmail());
        User user = userMapper.selectOne(qw);
        if (user == null) {
            throw new RuntimeException("邮箱或密码错误");
        }
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new RuntimeException("邮箱或密码错误");
        }

        // 注意：网关通常负责签发/校验token。如果你需要服务端签发 token，请使用 common.JwtUtil 注入并生成 token。
        // 这里我们返回空 token（或可抛出提示前端调用网关登录）。为了兼容接口文档，我们返回一个 placeholder。
        String token = "PLACEHOLDER_TOKEN_YOU_SHOULD_GET_FROM_GATEWAY_OR_AUTH_SERVER";

        LoginResponse.UserSummary summary = new LoginResponse.UserSummary(user.getId(), user.getUsername(), user.getRole());
        return new LoginResponse(token, LocalDateTime.now().plusDays(1), summary);
    }

    @Override
    public ApiResponse<String> logout(String token) {
        // 方案1：前端清空 JWT 即可，后端只返回成功
        return ApiResponse.success("退出成功");
    }

}